package com.yc.cloud.admin.service.impl;

import com.yc.cloud.common.orm.CommonPage;
import com.yc.cloud.common.basic.dto.BasePageReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelVersionCreateReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelVersionQueryReqDTO;
import com.yc.cloud.admin.dto.request.AlgModelVersionUpdateReqDTO;
import com.yc.cloud.admin.vo.AlgModelVersionVo;
import com.yc.cloud.entity.AlgModelVersion;
import com.yc.cloud.mapper.AlgModelVersionMapper;
import com.yc.cloud.admin.service.AlgModelVersionService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.api.enums.PublishStatusEnum;
import com.yc.cloud.common.oss.service.OssFileService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import java.util.Objects;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 算法模型版本表 服务实现类
 * </p>
 *
 * @author kinggu
 * @since 2025-07-11
 */
@Service
public class AlgModelVersionServiceImpl extends ServiceImpl<AlgModelVersionMapper, AlgModelVersion> implements AlgModelVersionService {

    @Resource
    private OssFileService ossFileService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(AlgModelVersionCreateReqDTO createReqDTO) {
        // 检查同一模型下是否存在相同版本号
        QueryWrapper<AlgModelVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AlgModelVersion.ModelId, createReqDTO.getModelId())
                    .eq(AlgModelVersion.ModelVersion, createReqDTO.getModelVersion());
        if (baseMapper.exists(queryWrapper)) {
            Asserts.fail("该模型下已存在相同的版本号: " + createReqDTO.getModelVersion());
        }

        AlgModelVersion entity = new AlgModelVersion();
        BeanUtils.copyProperties(createReqDTO, entity);

        // 如果没有其他已发布的版本，则将此版本自动设为发布状态
        List<AlgModelVersion> allVersions = getAllVersionsByModelId(createReqDTO.getModelId());
        boolean hasPublishedVersion = allVersions.stream()
            .anyMatch(v -> PublishStatusEnum.isPublished(v.getPublishStatus()));

        if (!hasPublishedVersion) {
            entity.setPublishStatus(PublishStatusEnum.PUBLISHED.getValue());
        } else {
            // 否则，根据DTO的status字段或默认为未发布
            if (createReqDTO.getStatus() != null && Boolean.TRUE.equals(createReqDTO.getStatus())) {
                 entity.setPublishStatus(PublishStatusEnum.PUBLISHED.getValue());
            } else {
                 entity.setPublishStatus(PublishStatusEnum.UNPUBLISHED.getValue());
            }
        }
        
        return save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(AlgModelVersionUpdateReqDTO updateReqDTO) {
        AlgModelVersion entity = new AlgModelVersion();
        BeanUtils.copyProperties(updateReqDTO, entity);
        return updateById(entity);
    }

    @Override
    public Boolean publish(Long id) {
        // 1. 获取要发布的版本
        AlgModelVersion versionToPublish = getById(id);
        if (versionToPublish == null) {
            Asserts.fail("模型版本不存在");
            return false;
        }

        // 2. 将该模型下的其他所有版本设置为未发布
        List<AlgModelVersion> allVersionsOfModel = getAllVersionsByModelId(versionToPublish.getModelId());
        for (AlgModelVersion version : allVersionsOfModel) {
             if(id == version.getId()){
                version.setPublishStatus(PublishStatusEnum.PUBLISHED.getValue());
             }else{
                version.setPublishStatus(PublishStatusEnum.UNPUBLISHED.getValue());
             }
        }

        return updateBatchById(allVersionsOfModel);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unpublish(Long id) {
        AlgModelVersion versionToUnpublish = getById(id);
        if (versionToUnpublish == null) {
            Asserts.fail("模型版本不存在");
            return false;
        }

        if (PublishStatusEnum.isPublished(versionToUnpublish.getPublishStatus())) {
            versionToUnpublish.setPublishStatus(PublishStatusEnum.UNPUBLISHED.getValue());
            updateById(versionToUnpublish);
        }

        return true;
    }

    @Override
    public CommonPage<AlgModelVersionVo> list(BasePageReqDTO pageReqDTO) {
        // 调用新的方法，保持向后兼容
        if (pageReqDTO instanceof AlgModelVersionQueryReqDTO) {
            return list((AlgModelVersionQueryReqDTO) pageReqDTO);
        }
        
        AlgModelVersionQueryReqDTO queryReqDTO = new AlgModelVersionQueryReqDTO();
        BeanUtils.copyProperties(pageReqDTO, queryReqDTO);
        return list(queryReqDTO);
    }
    
    @Override
    public CommonPage<AlgModelVersionVo> list(AlgModelVersionQueryReqDTO queryReqDTO) {
        QueryWrapper<AlgModelVersion> queryWrapper = new QueryWrapper<>();

        // 1. 添加筛选条件
        if (queryReqDTO.getModelId() != null) {
            queryWrapper.eq(AlgModelVersion.ModelId, queryReqDTO.getModelId());
        }

        if (queryReqDTO.getPublishStatus() != null) {
            queryWrapper.eq(AlgModelVersion.PublishStatus, queryReqDTO.getPublishStatus());
        }

        // TODO: algorithmId 过滤需要通过 JOIN alg_model 表实现，当前暂不支持该条件过滤
        // 如需支持，需在 AlgModelVersionMapper 中添加自定义 SQL 实现 JOIN 查询

        // 2. 排序
        if (StrUtil.isNotEmpty(queryReqDTO.getSortBy())) {
            if (Objects.equals(BasePageReqDTO.ORDER_DESC, queryReqDTO.getOrder())) {
                queryWrapper.orderByDesc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            } else {
                queryWrapper.orderByAsc(StrUtil.toUnderlineCase(queryReqDTO.getSortBy()));
            }
        } else {
            // 默认按创建时间倒序
            queryWrapper.orderByDesc("create_time");
        }

        // 3. 关键字模糊查询
        if (StrUtil.isNotEmpty(queryReqDTO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper.like(AlgModelVersion.ModelVersion, queryReqDTO.getKeyword())
                                              .or()
                                              .like(AlgModelVersion.ReleaseNotes, queryReqDTO.getKeyword()));
        }

        // 4. 分页查询
        if (Boolean.TRUE.equals(queryReqDTO.getPage())) {
            Page<AlgModelVersion> page = new Page<>(queryReqDTO.getPageNum(), queryReqDTO.getPageSize());
            Page<AlgModelVersion> dbPage = baseMapper.selectPage(page, queryWrapper);
            List<AlgModelVersionVo> voList = convertToVoList(dbPage.getRecords());
            // 手动组装分页结果，确保 VO 转换使用我们自定义的 convertToVo 方法
            CommonPage<AlgModelVersionVo> result = new CommonPage<>();
            result.setTotalPage((int) dbPage.getPages());
            result.setPageNum((int) dbPage.getCurrent());
            result.setPageSize((int) dbPage.getSize());
            result.setTotal(dbPage.getTotal());
            result.setList(voList);
            return result;
        } else {
            List<AlgModelVersion> allRecords = baseMapper.selectList(queryWrapper);
            CommonPage<AlgModelVersionVo> result = new CommonPage<>();
            result.setList(convertToVoList(allRecords));
            result.setTotal((long) allRecords.size());
            result.setPageNum(1);
            result.setPageSize(allRecords.size());
            result.setTotalPage(1);
            return result;
        }
    }

    @Override
    public AlgModelVersionVo getVOById(Long id) {
        AlgModelVersion entity = getById(id);
        return convertToVo(entity);
    }

    @Override
    public List<AlgModelVersionVo> convertToVoList(List<AlgModelVersion> entityList) {
        if (entityList == null) {
            return null;
        }
        return entityList.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }

    private AlgModelVersionVo convertToVo(AlgModelVersion entity) {
        if (entity == null) {
            return null;
        }
        AlgModelVersionVo vo = new AlgModelVersionVo();
        BeanUtils.copyProperties(entity, vo);

        // 获取模型文件的下载地址
        if (entity.getFileId() != null) {
            String downloadUrl = ossFileService.getOssFileUrl(String.valueOf(entity.getFileId()));
            vo.setDownloadUrl(downloadUrl);
        }

        return vo;
    }

    @Override
    public AlgModelVersion get(Long id) {
        return getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        return removeById(id);
    }

       /**
     * 根据模型ID获取所有版本
     * @param modelId 模型ID
     * @return 该模型下的所有版本列表
     */
    private List<AlgModelVersion> getAllVersionsByModelId(Long modelId) {
        QueryWrapper<AlgModelVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AlgModelVersion.ModelId, modelId);
        return this.list(queryWrapper);
    }


    @Override
    public AlgModelVersionVo getPublishedVersionByModelId(Long modelId) {
        QueryWrapper<AlgModelVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(AlgModelVersion.ModelId, modelId)
                .eq(AlgModelVersion.PublishStatus, PublishStatusEnum.PUBLISHED.getValue())
                .last("LIMIT 1"); // 优化查询，找到一个就返回
        AlgModelVersion entity = getOne(queryWrapper);
        return convertToVo(entity);
    }
} 